/*
 * Chandni Sabhaya
 * Reviewer Central panel.
 * Date: 12/3/2011
 */

package gui.reviewer;

import gui.CAControl;

import java.awt.Component;
import java.awt.GridLayout;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

import caobject.Conference;
import caobject.Manuscript;
import caobject.Review;
import caobject.User;

/**
 * This is the class that holds the center panel of the frame
 * when the user is a reviewer and displays a table in
 * the frame with the manuscripts and their statuses.
 * 
 * @author Chandni Sabhaya
 * @version 12/3/2011
 */
@SuppressWarnings("serial")
public class ReviewerCenterPanel extends JPanel implements Observer
{	
	private static final int ROW = 1; //defalut raw for table
	private static final int COLUMN = 4; //defalut raw for table
	
	private static final String REVIEWED = "Reviewed"; // paper is reviewed 
	private static final String NOT_REVIEWED = "Unreviewed"; // paper is not reviewed
	
	private JTable my_table; //table for reviewer 	
	private User my_user; // current reviewer. 
	
	/**
	 * the set of manuscripts that assigned to the current reviewer.  
	 */
	private Set<Manuscript> my_manuscripts; 
	
	/**
	 * map of manuscript title with the status (reviewed/not reviewed).
	 */
	private Map<String, String> my_manuscript_statuses;
	
	/**
	 * Panel Conference Reference.
	 */
	private final Conference my_conf;	
	
	
	DefaultTableModel my_model = null;
	
	/**
	 * Control.
	 */
	private final CAControl my_control;
	
	public ReviewerCenterPanel( final Conference the_conf, final User the_user, 
			final CAControl the_control) 
	{
		super(new GridLayout(1,0));
		my_conf = the_conf;
		my_control = the_control;
		my_user = the_user;
		my_table = new JTable();
		my_manuscripts = new HashSet<Manuscript>();
		my_manuscript_statuses = new HashMap<String, String>();
		
		// find only manuscripts that i can review
		loadMyManuscripts();
		determineManuscriptStatuses();
		
		// create a table
		createTable();
	}
	
	/**
	 * loads the manuscripts for the current reviewer. 
	 */
	private void loadMyManuscripts(){
		
		my_manuscripts = new HashSet<Manuscript>();

		//get all the papers from the conference 
		Set<Manuscript> manuscripts = my_conf.getManuscripts();
		
		//using iterator for all papers 
		Iterator<Manuscript> iterManuscripts = manuscripts.iterator();
		
		while(iterManuscripts.hasNext()) {
			Manuscript manuscript = iterManuscripts.next();
			
			//get all reviewers for each paper
			List<User> reviewers = manuscript.getReviewers();
						
			for (User r : reviewers) {
				//get the paper if correct (this) reviewer found
				if(r.getUserName().equals(this.my_user.getUserName())) {
					my_manuscripts.add(manuscript);
					break; 
				}
			}
			
		} // end of while loop
	}
	
	/**
	 * This method initializes the each mapnuscript's title with the status of 
	 * the paper has been reviewed or not. 
	 */
	public void determineManuscriptStatuses()
	{
		my_manuscript_statuses = new HashMap<String,String>();
		
		Iterator<Manuscript> iterManus = my_manuscripts.iterator();
		
		while(iterManus.hasNext()) {
			Manuscript manuscript = iterManus.next();
			
			String status = null;
		
			// check the status to see whether or not the paper is reviewed .
			if(manuscript.getReviewsSize() > 0) {
				ArrayList<Review> reviews = manuscript.getReviews();
				for(Review r : reviews) {
					if(r.getReviewerName().equals(my_user.getUserName()) && r.getText() != null) {
						status = REVIEWED; //review is submitted
						break; // break the for each loop
					} else {
						status = REVIEWED; //review is submitted
						break;
					}
				}
			} else {
				status = NOT_REVIEWED; //review is not submitted
			}
			
			my_manuscript_statuses.put(manuscript.getTitle(), status);
		}
	}
	
	/**
	 * sets the table with the default row and column. 
	 */
	private void createTable() 
	{			
		my_model = new DefaultTableModel();
		
		my_model.addColumn("Action");
		my_model.addColumn("Author");
		my_model.addColumn("Paper");
		my_model.addColumn("Status");
	    

	    // Create a table with 1-rows and 4 -columns
	    my_table = new JTable( my_model){
	    	public boolean isCellEditable(int rowIndex, int colIndex) {
	    		if( colIndex > 0 )
	    			return false; //Disallow the editing of non-button cells
	    		else
	    			return true;
	    	}
	    };
	    
	    int v = ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS;  
		int h = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER;
		JScrollPane scroller = new javax.swing.JScrollPane(my_table, v, h); 

	    my_table.setRowSorter(null);
	    
	    loadDataIntoTable( my_model );

	    my_table.getColumnModel().getColumn(0).setCellEditor(new ButtonEditor());
	    my_table.getColumnModel().getColumn(0).setCellRenderer(new ButtonRenderer());

	    my_model.fireTableDataChanged();
	    
	    //Add the scroll pane to this panel.
	    this.add(scroller);  
	    
	}
	
	/**
	 * initialize the central table. 
	 */	
	private void loadDataIntoTable(DefaultTableModel model) {
		
		int rows = model.getRowCount();
		int columns = model.getColumnCount();
		for ( int i = 0; i < rows ; i++ )
		{
			model.removeRow( 0 );
		}

		// now iterating through the only this reviewers papers		
		Iterator<Manuscript> iterManus = my_manuscripts.iterator();
		while(iterManus.hasNext()) {
			Manuscript manuscript = iterManus.next();
			String author_name = manuscript.getAuthor();
			String paper_title = manuscript.getTitle();
			
			//---------------------------------------------------------------//
			// check the status to see that the paper is reviewed or not
			String status = my_manuscript_statuses.get(paper_title);
			
			model.addRow( new String[]{ "#", author_name, paper_title, status });
		}
		
	}
	
	/**
	 * Method used to update the panel
	 */
	@Override
	public void update(Observable arg0, Object arg1) 
	{
		// TODO Auto-generated method stub
		
	}
	
//	//--------------------------------test------------------------------------//
//	
//	/**
//     * Create the GUI and show it.  For thread safety,
//     * this method should be invoked from the
//     * event-dispatching thread.
//     */
//    private static void createAndShowGUI() 
//    {
//        //Create and set up the window.
//        JFrame frame = new JFrame("SimpleTableDemo");
//        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//        
//		User chair = new User("Conf Chair", EnumRole.PROGRAMCHAIR);
//		Conference conf = new Conference( chair, "Test Conference");
//		
//		User reviewer = new User("Reviewer", EnumRole.REVIEWER);
//		conf.addUser(reviewer);
//		
//		User reviewer2 = new User("Reviewer2", EnumRole.REVIEWER);
//		conf.addUser(reviewer2);
//		
//		Manuscript manu1 = new Manuscript("Author1", "Manuscript1","This is Manuscript1 text");
//		manu1.addReviewer(reviewer);
//		conf.addManuscript(manu1);
//		
//		Manuscript manu2 = new Manuscript("Author2", "Manuscript2","This is Manuscript2 text");
//		manu2.addReviewer(reviewer);
//		conf.addManuscript(manu2);
//		
//		Manuscript manu3 = new Manuscript("Author3", "Manuscript3","This is Manuscript3 text");
//		manu3.addReviewer(reviewer2);
//		conf.addManuscript(manu3);
//
//		Manuscript manu4 = new Manuscript("Author4", "Manuscript4","This is Manuscript4 text");
//		manu4.addReviewer(reviewer);
//		manu4.addReview(reviewer, "this paper sucks");
//		
//		conf.addManuscript(manu4);
//
//        //Create and set up the content pane.
//        ReviewerCenterPanel centralPane = new ReviewerCenterPanel(conf, reviewer, new CAControl() );
//        centralPane.setOpaque(true); //content panes must be opaque
//        frame.setContentPane(centralPane);
//        //frame.add(centralPane);
//
//        //Display the window.
//        frame.pack();
//        frame.setVisible(true);
//        frame.setResizable(false);
//    }
    
  //--------------------------------test------------------------------------//

    
	/**
	 * ButtonEditor class for the Action for Button.
	 * 
	 * @author Chandni Sabhaya
	 */
	public class ButtonEditor extends JButton implements TableCellEditor {
		
		/**
		 * the public constructor. 
		 */
	    public ButtonEditor() {
	        super("Button");
	    }

	    public Component getTableCellEditorComponent(JTable table, Object value,
	            boolean isSelected, int row, int column) {
	        	
	    	buttonPressed(table, row, column);
	        
	    	String status = (String) table.getModel().getValueAt(row, column+3);
	    	if( status.equalsIgnoreCase( REVIEWED ) ) {
	    		setText("Update Review");
	    	} 
	    	else {
	    		setText("Add Review");
	    	}
	        
	        return this;
	    }

	    public void cancelCellEditing() {
	    }

	    public boolean stopCellEditing() {        
	        return true;
	    }

	    public Object getCellEditorValue() {
	        return null;
	    }

	    public boolean isCellEditable(EventObject anEvent) {
	        return true;
	    }

	    public boolean shouldSelectCell(EventObject anEvent) {
	        return false;
	    }

	    public void addCellEditorListener(CellEditorListener l) {
	    }

	    public void removeCellEditorListener(CellEditorListener l) {
	    }
	    
	    protected void fireCellEditing(ChangeEvent e){
	        
	    }
	    
	    /**
	     * helper method for the buttonPressed() method. 
	     * 
	     * @param table the table
	     * @param row	row number in the table 
	     * @param column column number in the table
	     */
	    private void showFileChooser(JTable table, int row, int column){
	    	String text = null;
	    	JFileChooser file_chooser = new JFileChooser();
			final int open_dialog = file_chooser.showOpenDialog(null);			
			// APPROVE_OPTION = Return value if approve (yes, ok) is chosen.
			if (open_dialog == JFileChooser.APPROVE_OPTION) {			
				final File user_file = file_chooser.getSelectedFile();
				try {
					if (user_file.getName().endsWith("txt")) {
						text = Review.getFileText(user_file).toString();
					} else {
						JOptionPane.showMessageDialog(null,
								"File does not end with .txt" + user_file,
								"Message", JOptionPane.INFORMATION_MESSAGE);
					}
				} catch (final IOException e) {
					JOptionPane.showMessageDialog(null, e.getMessage(),
							"Error Message", JOptionPane.ERROR_MESSAGE);
				}
				
				String manuscript_author = (String) table.getModel().getValueAt(row, column + 1 );
				String manuscript_title = (String) table.getModel().getValueAt(row, column + 2 );
				
				Manuscript man = my_conf.getAManuscript( manuscript_author, manuscript_title );
				man.addReview(my_user, text);
		        
				// find only manuscripts that i can review
				loadMyManuscripts();
				determineManuscriptStatuses();				
				// create a table
				loadDataIntoTable( my_model);	
				
				
			}
	    }
	    
	    /**
	     * this method get calls by clicking on the button from the table.
	     * @param table the table
	     * @param row	row number in the table 
	     * @param column column number in the table 
	     */
	    private void buttonPressed(JTable table, int row, int column)
	    {
			
			//first make sure the status is not reviewed
			String manuscript_status = (String) table.getModel().getValueAt(row, column + 3);
			
			if (manuscript_status.equals(REVIEWED)) 
			{
				
				int confirm = JOptionPane.showConfirmDialog(null, 
					"Are You Sure you want to replace the submitted review?");				
				if( confirm == JOptionPane.YES_OPTION )
				{
					// Do JFile CHooser!!!
					showFileChooser(table, row, column);
				}	    
				
	        }
			else if (manuscript_status.equals(NOT_REVIEWED))
			{
				showFileChooser(table, row, column);
			}

			this.setFocusable(true);
			this.setEnabled(true);
			
	    }

	}
	
	/**
	 * ButtonRender class 
	 * 
	 * @author Chandni
	 *
	 */
	public class ButtonRenderer extends JButton implements TableCellRenderer {

	    public Component getTableCellRendererComponent(JTable table, Object value,
	            boolean isSelected, boolean hasFocus, int row, int column) {
	    	
	    	
	    	String status = (String) table.getModel().getValueAt(row, column+3);
	    	if( status.equalsIgnoreCase( REVIEWED ) ) {
	    		setText("Update Review");
	    	} 
	    	else {
	    		setText("Add Review");
	    	}
	    	
	    	this.setSelected(false);
	        return this;
	        
	        
	    }
	}
		
}
